package com.yuantu.judiciary.model.dto;

import com.yuantu.judiciary.model.enums.CaseCategory;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.beans.BeanUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 线上-司法涉诉接口调用信息
 *
 * @author syw
 * @since 2024-02-07
 **/
@Data
public class ResJudicialDataProdDTO {
    private String id;
    private ResJudicialDataDTO.Detail detail;
    private ResDishonestDataDTO sx;
    private ResLimitDataDTO xg;

    @Data
    @ApiModel("涉诉案件详情")
    public class Detail {
        @ApiModelProperty("管辖案件")
        private ResJudicialDataDTO.Detail.Jurisdict jurisdict;
        @ApiModelProperty("非诉保全审查案件")
        private ResJudicialDataDTO.Detail.Preservation preservation;
        @ApiModelProperty("行政案件")
        private ResJudicialDataDTO.Detail.Administrative administrative;
        @ApiModelProperty("民事案件")
        private ResJudicialDataDTO.Detail.Civil civil;
        @ApiModelProperty("执行案件")
        private ResJudicialDataDTO.Detail.Implement implement;
        @ApiModelProperty("刑事案件")
        private ResJudicialDataDTO.Detail.Criminal criminal;
        @ApiModelProperty("强制清算与破产案件")
        private ResJudicialDataDTO.Detail.Bankrupt bankrupt;
        @ApiModelProperty("赔偿案件")
        private ResJudicialDataDTO.Detail.Compensate compensate;
        @ApiModelProperty("案件串联树")
        private CaseTreeDTO cases_tree;

        @Data
        public class Jurisdict {
            private List<CaseJurisdictionDTO> cases;
            private CaseCountDTO count;
        }

        @Data
        public class Preservation {
            private List<CasePreservationDTO> cases;
            private CaseCountDetailDTO count;
        }

        @Data
        public class Administrative {
            private List<CaseAdministrativeDTO> cases;
            private CaseCountDetailDTO count;
        }

        @Data
        public class Civil {
            private List<CaseCivilDTO> cases;
            private CaseCountDetailDTO count;
        }

        @Data
        public class Implement {
            private List<CaseImplementDTO> cases;
            private CaseCountDTO count;
        }

        @Data
        public class Criminal {
            private List<CaseCriminalDTO> cases;
            private CaseCountDetailDTO count;
        }

        @Data
        public class Bankrupt {
            private List<CaseBankruptDTO> cases;
            private CaseCountDTO count;
        }

        @Data
        public class Compensate {
            private List<CaseCompensateDTO> cases;
            private CaseCountDTO count;
        }
    }

    public Map<String, List<CaseDataDTO>> getCaseData() {
        Map<String, List<CaseDataDTO>> detailMap = new HashMap<>(16);
        detailMap.put(CaseCategory.JURISDICTION.getCode(), Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getJurisdict)
                .map(ResJudicialDataDTO.Detail.Jurisdict::getCases).orElse(new ArrayList<>()).stream().map(m -> {
                    CaseDataDTO caseDataDTO = new CaseDataDTO();
                    BeanUtils.copyProperties(m, caseDataDTO);
                    return caseDataDTO;
                }).collect(Collectors.toList()));
        detailMap.put(CaseCategory.PRESERVATION.getCode(), Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getPreservation)
                .map(ResJudicialDataDTO.Detail.Preservation::getCases).orElse(new ArrayList<>()).stream().map(m -> {
                    CaseDataDTO caseDataDTO = new CaseDataDTO();
                    BeanUtils.copyProperties(m, caseDataDTO);
                    return caseDataDTO;
                }).collect(Collectors.toList()));
        detailMap.put(CaseCategory.ADMINISTRATIVE.getCode(), Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getAdministrative)
                .map(ResJudicialDataDTO.Detail.Administrative::getCases).orElse(new ArrayList<>()).stream().map(m -> {
                    CaseDataDTO caseDataDTO = new CaseDataDTO();
                    BeanUtils.copyProperties(m, caseDataDTO);
                    return caseDataDTO;
                }).collect(Collectors.toList()));
        detailMap.put(CaseCategory.CIVIL.getCode(), Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCivil)
                .map(ResJudicialDataDTO.Detail.Civil::getCases).orElse(new ArrayList<>()).stream().map(m -> {
                    CaseDataDTO caseDataDTO = new CaseDataDTO();
                    BeanUtils.copyProperties(m, caseDataDTO);
                    return caseDataDTO;
                }).collect(Collectors.toList()));
        detailMap.put(CaseCategory.IMPLEMENT.getCode(), Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getImplement)
                .map(ResJudicialDataDTO.Detail.Implement::getCases).orElse(new ArrayList<>()).stream().map(m -> {
                    CaseDataDTO caseDataDTO = new CaseDataDTO();
                    BeanUtils.copyProperties(m, caseDataDTO);
                    return caseDataDTO;
                }).collect(Collectors.toList()));
        detailMap.put(CaseCategory.BANKRUPT.getCode(), Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getBankrupt)
                .map(ResJudicialDataDTO.Detail.Bankrupt::getCases).orElse(new ArrayList<>()).stream().map(m -> {
                    CaseDataDTO caseDataDTO = new CaseDataDTO();
                    BeanUtils.copyProperties(m, caseDataDTO);
                    return caseDataDTO;
                }).collect(Collectors.toList()));
        detailMap.put(CaseCategory.COMPENSATE.getCode(), Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCompensate)
                .map(ResJudicialDataDTO.Detail.Compensate::getCases).orElse(new ArrayList<>()).stream().map(m -> {
                    CaseDataDTO caseDataDTO = new CaseDataDTO();
                    BeanUtils.copyProperties(m, caseDataDTO);
                    return caseDataDTO;
                }).collect(Collectors.toList()));
        detailMap.put(CaseCategory.CRIMINAL.getCode(), Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCriminal)
                .map(ResJudicialDataDTO.Detail.Criminal::getCases).orElse(new ArrayList<>()).stream().map(m -> {
                    CaseDataDTO caseDataDTO = new CaseDataDTO();
                    BeanUtils.copyProperties(m, caseDataDTO);
                    return caseDataDTO;
                }).collect(Collectors.toList()));
        return detailMap;
    }

    public Map<String, CaseNumDTO> getCaseNum() {
        Map<String, CaseNumDTO> map = new HashMap<>(16);
        map.put(CaseCategory.JURISDICTION.getCode(), new CaseNumDTO(
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getJurisdict).map(ResJudicialDataDTO.Detail.Jurisdict::getCount).map(CaseCountDTO::getCount_total).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getJurisdict).map(ResJudicialDataDTO.Detail.Jurisdict::getCount).map(CaseCountDTO::getCount_wei_total).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getJurisdict).map(ResJudicialDataDTO.Detail.Jurisdict::getCount).map(CaseCountDTO::getCount_jie_total).orElse(0)
        ));
        map.put(CaseCategory.PRESERVATION.getCode(), new CaseNumDTO(
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getPreservation).map(ResJudicialDataDTO.Detail.Preservation::getCount).map(CaseCountDetailDTO::getCount_total_cases).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getPreservation).map(ResJudicialDataDTO.Detail.Preservation::getCount).map(CaseCountDetailDTO::getCount_wei_total_cases).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getPreservation).map(ResJudicialDataDTO.Detail.Preservation::getCount).map(CaseCountDetailDTO::getCount_jie_total_cases).orElse(0)
        ));
        map.put(CaseCategory.ADMINISTRATIVE.getCode(), new CaseNumDTO(
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getAdministrative).map(ResJudicialDataDTO.Detail.Administrative::getCount).map(CaseCountDetailDTO::getCount_total_cases).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getAdministrative).map(ResJudicialDataDTO.Detail.Administrative::getCount).map(CaseCountDetailDTO::getCount_wei_total_cases).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getAdministrative).map(ResJudicialDataDTO.Detail.Administrative::getCount).map(CaseCountDetailDTO::getCount_jie_total_cases).orElse(0)
        ));
        map.put(CaseCategory.CIVIL.getCode(), new CaseNumDTO(
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCivil).map(ResJudicialDataDTO.Detail.Civil::getCount).map(CaseCountDetailDTO::getCount_total_cases).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCivil).map(ResJudicialDataDTO.Detail.Civil::getCount).map(CaseCountDetailDTO::getCount_wei_total_cases).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCivil).map(ResJudicialDataDTO.Detail.Civil::getCount).map(CaseCountDetailDTO::getCount_jie_total_cases).orElse(0)
        ));
        map.put(CaseCategory.IMPLEMENT.getCode(), new CaseNumDTO(
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getImplement).map(ResJudicialDataDTO.Detail.Implement::getCount).map(CaseCountDTO::getCount_total).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getImplement).map(ResJudicialDataDTO.Detail.Implement::getCount).map(CaseCountDTO::getCount_wei_total).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getImplement).map(ResJudicialDataDTO.Detail.Implement::getCount).map(CaseCountDTO::getCount_jie_total).orElse(0)
        ));
        map.put(CaseCategory.BANKRUPT.getCode(), new CaseNumDTO(
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getBankrupt).map(ResJudicialDataDTO.Detail.Bankrupt::getCount).map(CaseCountDTO::getCount_total).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getBankrupt).map(ResJudicialDataDTO.Detail.Bankrupt::getCount).map(CaseCountDTO::getCount_wei_total).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getBankrupt).map(ResJudicialDataDTO.Detail.Bankrupt::getCount).map(CaseCountDTO::getCount_jie_total).orElse(0)
        ));
        map.put(CaseCategory.COMPENSATE.getCode(), new CaseNumDTO(
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCompensate).map(ResJudicialDataDTO.Detail.Compensate::getCount).map(CaseCountDTO::getCount_total).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCompensate).map(ResJudicialDataDTO.Detail.Compensate::getCount).map(CaseCountDTO::getCount_wei_total).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCompensate).map(ResJudicialDataDTO.Detail.Compensate::getCount).map(CaseCountDTO::getCount_jie_total).orElse(0)
        ));
        map.put(CaseCategory.CRIMINAL.getCode(),  new CaseNumDTO(
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCriminal).map(ResJudicialDataDTO.Detail.Criminal::getCount).map(CaseCountDetailDTO::getCount_total_cases).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCriminal).map(ResJudicialDataDTO.Detail.Criminal::getCount).map(CaseCountDetailDTO::getCount_wei_total_cases).orElse(0),
                Optional.ofNullable(detail).map(ResJudicialDataDTO.Detail::getCriminal).map(ResJudicialDataDTO.Detail.Criminal::getCount).map(CaseCountDetailDTO::getCount_jie_total_cases).orElse(0)
        ));
        return map;
    }
}
